package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.CartInfoMapper;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gsy
 * @date 2021年09月10日21:31
 * Description
 */
@Service
public class OrderInfoServiceImpl implements OrderInfoService {

    @Value("${ware.url}")
    private String wareUrl;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private CartInfoMapper cartInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    //远程调用库存系统库存够不够
    @Override
    public boolean hasStock(OrderDetail orderDetail) {
        String s = HttpClientUtil.doGet(wareUrl + "/hasStock?skuId=" + orderDetail.getSkuId() + "&num=" + orderDetail.getSkuNum());
        return "1".equals(s);

    }

    @Transactional
    @Override
    public Long saveOrderInfo(OrderInfo orderInfo) {

        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //订单交易编号
        String outTradeNo = "ATGUIFGU"
                + System.currentTimeMillis()
                + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        //交易内容
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuilder stringBuilder = new StringBuilder();
        for (OrderDetail orderDetail : orderDetailList) {
            String skuName = orderDetail.getSkuName();
            stringBuilder.append(skuName).append(" ");
            //商品实时价格
            BigDecimal price = productFeignClient.getPrice(orderDetail.getSkuId());
            orderDetail.setOrderPrice(price);
        }
        String tradeBody = stringBuilder.toString();
        if (tradeBody.length() > 100) {
            tradeBody = stringBuilder.substring(0, 100);
        }
        orderInfo.setTradeBody(tradeBody);

        //总金额  (在更新实时价格后计算)
        orderInfo.sumTotalAmount();

        //创建时间
        Calendar calendar = Calendar.getInstance();
        orderInfo.setCreateTime(calendar.getTime());
        //过期时间
        calendar.add(Calendar.HOUR, 2);
        orderInfo.setExpireTime(calendar.getTime());
        //进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        //保存订单
        orderInfoMapper.insert(orderInfo);
        //保存订单详情
        for (OrderDetail orderDetail : orderDetailList) {
            //订单id
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);

        }
        // 删除购物车已购买的商品
        //skuId集合
        List<String> skuIdList = orderDetailList.stream().map(orderDetail -> orderDetail.getSkuId().toString()).collect(Collectors.toList());
        //删除DB中的商品
        //批量删除
        cartInfoMapper.delete(new QueryWrapper<CartInfo>()
                .eq("user_id", orderInfo.getUserId().toString())
                .in("sku_id", skuIdList));
        //删除缓存中商品
        String cacheKeyCart = RedisConst.USER_KEY_PREFIX + orderInfo.getUserId() + RedisConst.USER_CART_KEY_SUFFIX;
        redisTemplate.opsForHash().delete(cacheKeyCart, skuIdList.toArray());

        // 发送延迟消息   定时未支付  取消订单
        rabbitService.sendDelayedMessage(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL, MqConst.ROUTING_ORDER_CANCEL, orderInfo.getId(), MqConst.DELAY_TIME);

        return orderInfo.getId();
    }

    @Override
    public void cancelOrder(Long orderId) {
        //根据id获取订单
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (orderInfo != null && orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.name())) {
            //订单过时未支付
            orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
            //修改订单状态
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            //修改进度状态
            orderInfoMapper.updateById(orderInfo);

        }

    }

    //查询订单金额及其相关信息
    @Override
    public OrderInfo getOrderInfo(Long orderId) {

        return orderInfoMapper.selectById(orderId);
    }

    //更新订单表
    @Override
    public void updateOrderStatusPaid(Long orderId, ProcessStatus processStatus) {
        //1:幂等性问题
        OrderInfo orderInfo = getOrderInfo(orderId);
        //未支付 更新 为已支付
        if (orderInfo != null && orderInfo.getOrderStatus().equals(OrderStatus.UNPAID.name())) {
            //第一次发生消息 更新为已支付
            //更新订单状态
            updateOrderStatus(orderInfo, processStatus);
            //发消息MQ 给仓库系统
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_WARE_STOCK,
                    MqConst.ROUTING_WARE_STOCK,
                    JSONObject.toJSONString(initWareOrder(orderId)));
            //更新进度状态
            updateOrderStatus(orderInfo,ProcessStatus.NOTIFIED_WARE);

        }

    }
    //拆单 TODO
    @Override
    public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
        //wareSkuMap: [{"wareId":"2","skuIds":["15"]},{"wareId":"1","skuIds":["7"]}]
        //原始订单
        OrderInfo orginOrderInfo = getOrderInfo(orderId);
        //拆分成多个子订单
        List<Map> wareSkuMapList = JSONObject.parseArray(wareSkuMap,Map.class);
        List<OrderInfo> orderInfoList = wareSkuMapList.stream().map(wareMap -> {
            //子订单
            OrderInfo subOrderInfo = new OrderInfo();
            BeanUtils.copyProperties(orginOrderInfo, subOrderInfo);
            //ID
            subOrderInfo.setId(null);
            //原始订单详情 集合
            List<OrderDetail> originOrderDetailList = orginOrderInfo.getOrderDetailList();
            //子订单详情集合
            List<OrderDetail> subOrderDetailList = new ArrayList<>();
            Map<String, OrderDetail> orderDetailMap = originOrderDetailList.stream()
                    .collect(Collectors.toMap(orderDetail -> orderDetail.getSkuId().toString(),
                            orderDetail -> orderDetail));
            //当前子订单对应所有的商品id
            List<String> skuIds = (List<String>) wareMap.get("skuIds");
            for (String skuId : skuIds) {
                OrderDetail orderDetail = orderDetailMap.get(skuId);
                if (orderDetail != null) {
                    subOrderDetailList.add(orderDetail);
                }
            }
            subOrderInfo.setOrderDetailList(subOrderDetailList);
            //金额
            subOrderInfo.sumTotalAmount();
            //父Id
            subOrderInfo.setParentOrderId(orginOrderInfo.getId());
            //仓库id
            subOrderInfo.setWareId(wareMap.get("wareId").toString());
            //保存子订单到DB中
            orderInfoMapper.insert(subOrderInfo);

            for (String skuId : skuIds) {
                OrderDetail orderDetail = orderDetailMap.get(skuId);
                if (orderDetail != null) {
                    orderDetail.setOrderId(subOrderInfo.getId());
                    orderDetailMapper.updateById(orderDetail);

                }
            }
            //修改订单状态 已拆分状态
            updateOrderStatus(subOrderInfo,ProcessStatus.SPLIT);
            return subOrderInfo;
        }).collect(Collectors.toList());


        return orderInfoList;
    }
    public Map initWareOrder(OrderInfo orderInfo){
        Map map = new HashMap<>();
        map.put("orderId", orderInfo.getId());
        map.put("consignee", orderInfo.getConsignee());
        map.put("consigneeTel", orderInfo.getConsigneeTel());
        map.put("orderComment", orderInfo.getOrderComment());
        map.put("orderBody", orderInfo.getTradeBody());
        map.put("deliveryAddress", orderInfo.getDeliveryAddress());
        map.put("wareId", orderInfo.getWareId());//附加字段
        map.put("paymentWay",
                orderInfo.getPaymentWay().equalsIgnoreCase("ONLINE") ? "2" : "1");
        List<Map> details = orderInfo.getOrderDetailList().stream().map(orderDetail -> {
            Map m = new HashMap();
            m.put("skuId", orderDetail.getSkuId());
            m.put("skuNum", orderDetail.getSkuNum());
            m.put("skuName", orderDetail.getSkuName());
            return m;
        }).collect(Collectors.toList());
        map.put("details", details);

        return map;

    }
    //组装消息
    public Map initWareOrder(Long orderId) {
        OrderInfo orderInfo = getOrderInfo(orderId);
       return initWareOrder(orderInfo);

    }

    private void updateOrderStatus(OrderInfo orderInfo, ProcessStatus processStatus) {
        //进度状态
        orderInfo.setProcessStatus(processStatus.name());
        //订单状态
        orderInfo.setOrderStatus(ProcessStatus.PAID.name());
    }
}
